#coding:utf-8
# from __future__ import print_function
import SimpleITK as sitk
import numpy as np
import os
import matplotlib.pyplot as plt
from PIL import Image

class MRI(object):
    def __init__(self,filename=None):
        self.itk_img = None
        self.img_array = None
        self.read(filename)
    def read(self, filename):
        if filename != None:
            if os.path.exists(filename):
                self.itk_img = sitk.ReadImage(filename)
                self.img_array = sitk.GetArrayFromImage(self.itk_img)
        return self
    def shape(self):
        return self.img_array.shape
    def displayZ(self, z):
        num_z, height, width = self.shape()
        if z < num_z and z > 0:
            plt.imshow(sitk.GetArrayViewFromImage(self.itk_img)[z,:,:], cmap='gray')
            plt.axis('off')
            plt.show()
    def imgArray(self):
        return self.img_array
    def getPoint(x,y,z):
        return self.imgArray()[z,y,x]
    def setPoint(x,y,z,v):
        self.imgArray()[z,y,x] = v
    def saveImgZ(self, z, fn):
        num_z, height, width = self.shape()
        if z < num_z and z > 0:
            plt.imshow(sitk.GetArrayViewFromImage(self.itk_img)[z,:,:], cmap='gray')
            # im = Image.fromarray(np.uint8(sitk.GetArrayViewFromImage(self.itk_img)[z,:,:]))
            # im = Image.fromarray(np.uint8(self.img_array[z,:,:]))
            # im.save(fn)
            plt.axis('off')
            plt.savefig(fn,dpi=100)
        

class Evaluator(object):
    #Evaluator only accept numpy
    @staticmethod
    def cal_dice(data,label):
        a = data[data>0].size
        b = label[label>0].size
        c = (data*label)
        c = c[c>0].size
        r = 2.0*c/(a+b)
        print r
        return r
    @staticmethod
    def Precision(data,label):
        #计算精度
        return Evaluator.c2all(data,label)[1]
    @staticmethod
    def Recall(data,label):
        #计算召回率
        return Evaluator.c2all(data,label)[2]
    @staticmethod
    def c2all(data,label):
        #计算准确率，精确率，召回率,F1
        def F1(TP,FN,FP,TN):
            return 2.0*TP/(2.0*TP+FP+FN)
        def Recall(TP,FN,FP,TN):
            return 1.0*TP/(TP+FN)
        def Precision(TP,FN,FP,TN):
            return 1.0*TP/(TP+FP)
        def Acc(TP,FN,FP,TN):
            return 1.0*(TP+TN)/label.size
        r1 = label - data
        FN = r1[r1>0].size
        FP = r1[r1<0].size
        r2 = label*data
        TP = r2[r2>0].size
        TN = label.size - (FN + FP+ TP)
        a= Acc(TP,FN,FP,TN)
        b =Precision(TP,FN,FP,TN)
        c = Recall(TP,FN,FP,TN)
        d = F1(TP,FN,FP,TN)
        print (a,b,c,d)
        return (a,b,c,d)
    

